#include "slm_thread.h"
#include "at_slm332.h"
#include "test_jsoncmd.h"
#include "updata_iot.h"
#include "t_at_ringbuffer.h"
#include "j_modbus.h"
#include "s_platform.h"
#include "cjson.h"
#include <stdbool.h>

void slm332_Task(void *parameter);  /// 上传
TaskHandle_t Serial_slm332_Handle = NULL;

void json_parse_Task(void *parameter);  ////解包
TaskHandle_t Serial_json_parse_Handle = NULL;

MQTT_MG_data MG_Reply_data;
rbuf  MQTT_MG_data_rbuf;

uint8_t t_cb(void *Ptx, uint8_t *dataBuf, uint8_t data_len, uint8_t *cmd_UrcString) {
    printf("cb _ . %s\n", cmd_UrcString);
    return 0;
}

void slm332_Task(void *parameter) {

    rbuf_init(&MQTT_MG_data_rbuf);
    slm332_creat(&slm_cfg);
    rdata_buff mg_payload;
    while (1) {
        if (rbuf_is_empty(&MQTT_MG_data_rbuf)!=RBUF_EMPTY) {
					  if(rbuf_pop(&MQTT_MG_data_rbuf,&mg_payload)==RBUF_OK){
					   uint8_t id_index=(uint8_t)(uintptr_t)mg_payload.arg;
              if (id_index < 4) {
                    pslm_mqtt_send_mqttdata(
                        SLM, &slm_cfg, 
                        id_index, // 动态ID
                        NULL,
                        (char*)mg_payload.buffer,
                        mg_payload.buf_len
                    );
                } else {
                    printf("[ERROR] Invalid client_id: %d\n", id_index);
                }
        }
			}
				vTaskDelay(pdMS_TO_TICKS(1)); 
		}
    
}
void queue_MG_send(uint8_t client_id, uint8_t *payload, uint16_t len) {
    // 参数校验
    if (payload == NULL || len == 0 || client_id >= 4) {
        printf("[ERROR] Invalid params: client_id=%d, len=%d\n", client_id, len);
        return;
    }

    // 检查队列状态
//    rbuf_err_t status = rbuf_is_full(&MQTT_MG_data_rbuf);
//    if (status == RBUF_FULL) {
//			  rbuf_clear(&MQTT_MG_data_rbuf);
//        printf("[WARN] Queue full! Discarding data from client %d\n", client_id);
//        return; // 直接丢弃数据
//    }
//    if (status != RBUF_OK) {
//        printf("[ERROR] Queue check failed: %d\n", status);
//        return;
//    }

    // 准备数据
    rdata_buff mg_reply_data_t;
    memset(&mg_reply_data_t, 0, sizeof(rdata_buff));
    
    // 安全设置参数
    mg_reply_data_t.arg = (void*)(uintptr_t)client_id;
    mg_reply_data_t.buf_len = (len > sizeof(mg_reply_data_t.buffer)) ? 
                            sizeof(mg_reply_data_t.buffer) : len;

    // 安全复制数据
    memcpy(mg_reply_data_t.buffer, payload, mg_reply_data_t.buf_len);

    // 压入缓冲区
    if (rbuf_push(&MQTT_MG_data_rbuf, &mg_reply_data_t) != RBUF_OK) {
        printf("[ERROR] Push failed for client %d\n", client_id);
    }
}

#define MAX_MODBUS_LEN 50
extern j_modbus_t *j_modbus_slave;
uint8_t slm_modbus_urc_cb(void *Ptx, uint8_t *dataBuf, uint8_t data_len, uint8_t *cmd_UrcString) {
    printf("--%s", dataBuf);
    uint8_t modbus[MAX_MODBUS_LEN] = {0};  // 存储提取的 Modbus 数据
    uint8_t modbus_len = 0;                // Modbus 数据长度
    int i;
    int first_quote = -1;   // 第一个 0x22 的索引
    int second_quote = -1;  // 第二个 0x22 的索引

    // 从后往前找第一个 0x22
    for (i = data_len - 1; i >= 0; i--) {
        if (dataBuf[i] == 0x22) {
            if (first_quote == -1) {
                first_quote = i;  // 记录第一个 0x22
            } else {
                if (first_quote - i - 1 == 0) {
                    continue;  // 如果差值为0，继续寻找下一个0x22
                } else {
                    second_quote = i;  // 记录第二个 0x22
                    break;             // 找到第二个 0x22，退出循环
                }
            }
        }
    }

    // 判断是否找到两个 0x22
    if (first_quote != -1 && second_quote != -1 && second_quote < first_quote) {
        modbus_len = first_quote - second_quote - 1;  // 计算 Modbus 指令长度

        // 判断长度是否超过最大允许长度
        if (modbus_len > MAX_MODBUS_LEN) {
            modbus_len = MAX_MODBUS_LEN;  // 截断长度
        }

        // 复制 Modbus 数据
        memcpy(modbus, &dataBuf[second_quote + 1], modbus_len);

        // 调试输出
        printf("Modbus len: %d\n", modbus_len);
        printf("Modbus data: ");
        for (int j = 0; j < modbus_len; j++) {
            printf("%02X ", modbus[j]);
        }
        printf("\n");
    } else {
        printf("not find \"0x22\" can't find Modbus data.\n");
    }

    //		j_modbus_set_arg(j_modbus_slave, MODBUS_PROTO_RTU, NULL);
    //	  j_modbus_set_send(j_modbus_slave , j_modbus_slave_mg_send_func, MODBUS_PROTO_RTU);
    //    j_modbus_slave_reply(j_modbus_slave,modbus, modbus_len, MODBUS_PROTO_RTU);//mobus协议处理
    return modbus_len;  // 返回 Modbus 数据长度
}

// 找到最外层的 JSON 边界
int find_outer_json_boundaries(char *input, char **start, char **end) {
    if (input == NULL || start == NULL || end == NULL) return -1;

    int brace_count = 0;       // 计数器
    char *first_brace = NULL;  // 最外层的 '{'
    char *last_brace = NULL;   // 最外层的 '}'

    for (char *p = input; *p != '\0'; p++) {
        if (*p == '{') {
            if (brace_count == 0) {
                first_brace = p;  // 记录最外层的 '{'
            }
            brace_count++;  // 计数器加 1
        } else if (*p == '}') {
            brace_count--;  // 计数器减 1
            if (brace_count == 0) {
                last_brace = p;  // 记录最外层的 '}'
                break;           // 找到最外层的边界，退出循环
            }
        }
    }

    if (first_brace == NULL || last_brace == NULL || brace_count != 0) {
        return -1;  // 未找到有效的 JSON 边界
    }

    *start = first_brace;
    *end = last_brace;
    return 0;
}
/**字符串转换为16进制数据*/
/**
 * @brief 将Modbus协议十六进制字符串转换为二进制数组
 *
 * @param command 输入字符串，必须为偶数长度且仅包含十六进制字符（0-9, a-f, A-F）
 * @param output 输出缓冲区，必须有足够空间存储 (strlen(command)/2) 字节
 * @param output_len 成功时返回转换后的字节数，失败时设置为0
 *
 * @note 错误处理逻辑：
 *   - 输入指针为NULL
 *   - 空字符串或奇数长度
 *   - 包含非十六进制字符
 *   - 输出缓冲区长度不足（通过strlen计算）
 */
static void parse_hex_command(const char *command, char *output, uint8_t *output_len) {
    // 初始化输出长度为0（默认错误状态）
    if (output_len != NULL) *output_len = 0;

    // ------------ 参数有效性校验 ------------
    // 防御性编程：所有指针必须有效
    if (command == NULL || output == NULL || output_len == NULL) return;

    // ------------ 输入基础校验 ------------
    const size_t command_len = strlen(command);
    if (command_len == 0 || command_len % 2 != 0) return;  // 空字符串或奇数长度

    // ------------ 字符合法性校验 ------------
    // 预校验所有字符均为合法十六进制（避免部分转换后失败）
    for (size_t i = 0; i < command_len; ++i) {
        if (!isxdigit((unsigned char)command[i])) return;
    }

    // ------------ 核心转换逻辑 ------------
    const size_t target_len = command_len / 2;
    for (size_t i = 0; i < target_len; ++i) {
        // 获取两个字符并转换为大写（兼容大小写输入）
        const char c_high = (char)toupper(command[2 * i]);
        const char c_low = (char)toupper(command[2 * i + 1]);

        // 手动转换十六进制（比strtol更高效）
        unsigned char value = 0;
        value |= (c_high >= 'A') ? (c_high - 'A' + 10) << 4 : (c_high - '0') << 4;
        value |= (c_low >= 'A') ? (c_low - 'A' + 10) : (c_low - '0');

        output[i] = value;
    }

    // 只有所有校验通过才更新输出长度
    *output_len = target_len;
}

/**
 * @brief 从 +QMTRECV 消息中提取 topic 字段
 * @param message 输入字符串，格式: +QMTRECV:
 * <client_idx>,<msg_id>,"<topic>",<payload_len>,"<payload>"
 * @param topic 输出缓冲区，用于存储提取的 topic（需提前分配足够空间）
 * @return true 成功提取，false 失败
 */
bool extract_topic(const char *message, char *topic) {
    if (!message || !topic) return false;

    // 查找第一个双引号的位置
    const char *first_quote = strchr(message, '"');
    if (!first_quote) return false;

    // 查找第二个双引号的位置（topic 的结束位置）
    const char *second_quote = strchr(first_quote + 1, '"');
    if (!second_quote) return false;

    // 计算 topic 长度
    size_t topic_len = second_quote - (first_quote + 1);
    if (topic_len == 0) return false;

    // 复制 topic 到输出缓冲区
    strncpy(topic, first_quote + 1, topic_len);
    topic[topic_len] = '\0';  // 确保字符串终止

    return true;
}
/**
 * @brief 解析 JSON 并提取 value、length 和 type
 * @param json_str 输入的 JSON 字符串
 * @param value 输出缓冲区，存储提取的 value 字符串
 * @param len 输出 value 的长度
 * @param type 输出 type 字段的值
 * @return 0 成功，-1 失败
 */
int json_decode(const char *json_str, char *value, uint8_t *len, uint8_t *type) {
    if (!json_str || !value || !len || !type) return -1;

    cJSON *root = cJSON_Parse(json_str);
    if (!root) {
        printf("JSON 解析失败\n");
        return -1;
    }

    // 提取 type 字段
    cJSON *type_item = cJSON_GetObjectItem(root, "type");
    if (cJSON_IsNumber(type_item)) {
        *type = (uint8_t)type_item->valueint;
    } else {
        cJSON_Delete(root);
        return -1;
    }
    // 提取 value 字段
    cJSON *value_item = cJSON_GetObjectItem(root, "value");
    if (cJSON_IsString(value_item) && value_item->valuestring != NULL) {
        strncpy(value, value_item->valuestring, strlen(value_item->valuestring));
        *len = (uint8_t)strlen(value_item->valuestring);
        value[*len] = '\0';  // 确保字符串终止
    } else {
        cJSON_Delete(root);
        return -1;
    }

    cJSON_Delete(root);
    return 0;
}

uint8_t slm_modbus_urc_huawei_cb(void *Ptx, uint8_t *dataBuf, uint8_t data_len,
                                 uint8_t *cmd_UrcString) {
    // 找到 JSON 结构体的起始和结束位置
    char *json_start = NULL;
    char *json_end = NULL;
    if (find_outer_json_boundaries((char *)dataBuf, &json_start, &json_end) != 0) {
        return 0;  // 未找到有效的 JSON 结构体，返回 0
    }

    // 提取 JSON 字符串
    size_t json_len = json_end - json_start + 1;
    char *json_str = malloc(json_len + 1);
    if (json_str == NULL) {
        return 0;  // 内存分配失败，返回 0
    }
    snprintf(json_str, json_len + 1, "%.*s", (int)json_len, json_start);

    // 解析 JSON 字符串
    cJSON *root = cJSON_Parse(json_str);
    free(json_str);  // 释放 JSON 字符串
    if (root == NULL) {
        return 0;  // 解析失败，返回 0
    }

    // 提取 modbus 字符串
    cJSON *paras = cJSON_GetObjectItem(root, "paras");
    if (paras == NULL) {
        cJSON_Delete(root);
        return 0;  // 提取失败，返回 0
    }

    cJSON *modbusItem = cJSON_GetObjectItem(paras, "modbus");
    if (modbusItem == NULL) {
        cJSON_Delete(root);
        return 0;  // 提取失败，返回 0
    }

    const char *modbusStr = cJSON_GetStringValue(modbusItem);
    if (modbusStr == NULL) {
        cJSON_Delete(root);
        return 0;  // 提取失败，返回 0
    }

    // 将 modbus 字符串转换为 uint8_t 数组
    uint8_t modbus[256];
    size_t modbus_len;
    // parse_modbus_command(modbusStr, modbus, &modbus_len);

    // 调用 Modbus 处理函数
    //    j_modbus_set_arg(j_modbus_slave, MODBUS_PROTO_RTU, NULL);
    //    j_modbus_set_send(j_modbus_slave, j_modbus_slave_mg_send_func, MODBUS_PROTO_RTU);
    //    j_modbus_slave_reply(j_modbus_slave, modbus, modbus_len, MODBUS_PROTO_RTU); // Modbus
    //    协议处理

    cJSON_Delete(root);  // 释放 JSON 对象

    return modbus_len;  // 返回 Modbus 数据长度
}
/******重写一下串口服务器逻辑********
 *@brief 接串口那边的数据回调（MG----->j3_Trans---->USART）
 *  extern void j3_trans_uart5_push_data(void*data, uint16_t len);---->注册到J3
 */
/**
 *@brief slm_uart_urc_cb MG接收线程处理逻辑 处理MQTT数据格式如下:
 *+QMTRECV: <client_idx>,<msg_id>,"<topic>"[<payload_len>,]“<payload>”
 *设计JSON处理payload:{"type":0(对数据的处理方式)[0-hex,1-string,2-other],"value":"12313213211132"(字符串传入),"arg":12144(用户自定义参数)}
 */
uint8_t slm_uart_decode_urc_cb(void *Ptx, uint8_t *dataBuf, uint8_t data_len, uint8_t *cmd_UrcString) {
    char topic[256];  // 改为局部变量
    char cmd[256];
    char cmd_hex[256];
    char *json_start = NULL;
    char *json_end = NULL;
    uint8_t len, len_hex, type;
    uint16_t index = slm_cfg.slm33_mqttc_num; // 默认设为无效值

    // 1. 提取 JSON
    if (find_outer_json_boundaries((char *)dataBuf, &json_start, &json_end) != 0) {
        return 0;
    }
    size_t json_len = json_end - json_start + 1;
    if (json_len >= 256) {  // 边界检查
        return 0;
    }
    char *json_str = AT_MALLOC(json_len + 1);
    if (!json_str) return 0;
    snprintf(json_str, json_len + 1, "%.*s", (int)json_len, json_start);

    // 2. 解析 JSON 和 Topic
    json_decode(json_str, cmd, &len, &type);
    extract_topic((const char *)dataBuf, topic);

    // 3. 处理十六进制数据
    if (type == 0) {
        parse_hex_command(cmd, cmd_hex, &len_hex);
        len = len_hex;
    }

    // 4. 匹配 Topic
    for (int i = 0; i < slm_cfg.slm33_mqttc_num; i++) {
        if (strcmp(topic, slm_cfg.smqtt[i].subtopic) == 0) {
            index = i;
            break;
        }
    }

    // 5. 分发数据
    switch (index) {
        case 0: mqqtc_sned_other_interface_1(type ? cmd : cmd_hex, len); break;
        case 1: mqqtc_sned_other_interface_2(type ? cmd : cmd_hex, len); break;
        case 2: mqqtc_sned_other_interface_3(type ? cmd : cmd_hex, len); break;
        case 3: mqqtc_sned_other_interface_4(type ? cmd : cmd_hex, len); break;
        default: printf("[WARN] Unknown topic: %s\n", topic);
    }

    AT_FREE(json_str);  // 释放内存
    return 1;
}
void json_parse_Task(void *parameter) {
    while (1) {
        mqtt_modbus_urc_decode(SLM, slm_uart_decode_urc_cb, (uint8_t *)"+QMTRECV:");
        vTaskDelay(1);
    }
}

void slm_task_create(void) {
    xTaskCreate(slm332_Task, "slm", 900, NULL, 1, &Serial_slm332_Handle);  //
    xTaskCreate(json_parse_Task, "slmd_decode", 500, NULL, 1, &Serial_json_parse_Handle);
}